Vue.component('tree', {
	template: `
		<div class="wrap">
			<div class="sign" 
					@click.stop="toggleOpen($event, data)" 
					@contextmenu.prevent.stop="showContextMenu($event, data)"
					@mouseover.stop="handleMouseEvt($event, data, 'over')" 
					@mouseout.stop="handleMouseEvt($event, data, 'out')">
				<div class="hover" v-show="selfHover" :style="hoverStyle"></div>
				<div class="selected" v-show="selfSelected" :style="selectedStyle"></div>
				<div class="content">
					<span class="icon" :class="signCls"></span>
					<span>{{data.name}}</span>
				</div>
			</div>
			<div class="children"
					v-if="data.childNodes.length > 0"
					v-show="data.childOpen">
				<tree v-for="(item, posi) in data.childNodes" :key="item.id"
						:node="item">
				</tree>			
			</div>
		</div>
	`,
	props: {
		node: {
			type: Object,
			default: function(){
				return {};
			}
		}
	
	},

	data: function(){
		let self = this;
		let data = self.node;
		return {
			data: {
				id: data.id,
				type: data.type,
				name: data.name,
				value: data.value,
				childNodes: data.childNodes,
				childOpen: false,
			},
			selfHover: false,
			hoverStyle: {
				left: '0px',
				width: 'calc(100%)',
			},
			selfSelected: false,
			selectedStyle: {
				left: '0px',
				width: 'calc(100%)',
			},
			nodeShowLevel: '',
		};

	},
	
	watch: {
		node: {
			deep: true,
			handler: function(newVal, oldValue){
				this.data = newVal;
			}

		}
	
	},

	computed: {
		showNode: function(){
			let self = this;
			let showLevel = self.nodeShowLevel
			if('noText' == showLevel){
				return Node.TEXT_NODE != self.data.type;
			}
			if('validText' == showLevel
				&& Node.TEXT_NODE == self.data.type){
				return self.isValidText(self.data.value);
			}
			return true;

		},

		signCls: function(){
			let self = this;
			if(self.data.childNodes.length > 0){
				return self.data.childOpen ? 'icofont-caret-down' : 'icofont-caret-right';
			}
			return 'icofont-none';

		}
	
	},

	methods: {
		isValidText: function(text){
			let self = this;
			let txtVal = null == text ? '' : text.trim();
			return utils.notEmpty(txtVal);

		},

		toggleOpen: function(event, node){
			let self = this;
			node.childOpen = !node.childOpen;
			self.$bus.$emit('node-clicked', {event: event, node: node});

		},

		handleMouseEvt: function(event, node, type){
			let self = this;
			self.$bus.$emit('node-hover', {type: type, event: event, node: node});

		},

		showContextMenu: function(event, node){
			let self = this;
			//self.$bus.$emit('node-clicked', {event: event, node: node});
			self.$bus.$emit('show-context-menu', {event: event});
			//self.$bus.$emit('show-console');

		}

	},
	
	created: function(){
		let self = this;
		self.$bus.$on('node-clicked', function(evtMsg){
			let node = evtMsg.node;
			self.selfSelected = node.id == self.data.id;
			if(self.selfSelected){
				let targetNode = evtMsg.event.target;
				let boundingClientRect = targetNode.getBoundingClientRect();
				let leftOffsetPx = boundingClientRect.left + 'px';
				let selectedStyle = {
					left: '-' + leftOffsetPx,
					width: 'calc(100% + ' + leftOffsetPx + ')'
				}
				self.selectedStyle = selectedStyle;
			}
		
		});
		
		self.$bus.$on('node-hover', function(evtMsg){
			let node = evtMsg.node;
			self.selfHover = 'over' == evtMsg.type && node.id == self.data.id;
			if(self.selfHover){
				let targetNode = evtMsg.event.target;
				let boundingClientRect = targetNode.getBoundingClientRect();
				let leftOffsetPx = boundingClientRect.left + 'px';
				let hoverStyle = {
					left: '-' + leftOffsetPx,
					width: 'calc(100% + ' + leftOffsetPx + ')'
				}
				self.hoverStyle = hoverStyle;
			}
		
		});

		self.$bus.$on('cfg-change', function(evtMsg){
			let cfg = evtMsg.cfg;
			if('view' == cfg.name){
				self.nodeShowLevel = evtMsg.newVal;
			}
		
		});

	},
	
	updated: function(){
		let self = this;
	
	}

});